<?php
// +----------------------------------------------------------------------
// | ZGUAN [ 致力于帮助更多的中小企业物联网转型 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.zguan.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ZGUAN 并不是自由软件，未经许可不能去掉ZGUAN 相关版权
// +----------------------------------------------------------------------
// | Author: ZGUAN Team <admin@zguan.cn>  0769-82282996  15899929162
// +----------------------------------------------------------------------
namespace app\common\repositories\room;

use app\common\dao\room\RoomBasicDao;
use app\common\repositories\BaseRepository;
use app\common\repositories\property\users\PropertyUsersLogRepository;
use app\common\repositories\system\upload\SystemUploadFileRepository;
use think\exception\ValidateException;
use think\facade\Db;

/**
 * Class RoomBasicRepository
 *
 * @mixin RoomBasicDao
 */
class RoomBasicRepository extends BaseRepository
{

    public function __construct(RoomBasicDao $dao)
    {
        $this->dao = $dao;
    }

    public function getPropertyList(array $where, $page, $limit, int $propertyId = null)
    {
        $query = $this->dao->search($where, $propertyId);
        $count = $query->count();
        $list = $query->page($page, $limit)
            ->append(['full_room_name', 'house_type', 'label_list'])
            ->order('id', 'desc')
            ->select();
        return compact('count', 'list');
    }

    /**
     *  获取房间列表
     * @param array $where
     * @param $page
     * @param $limit
     * @param int|null $propertyId
     * @return array
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-06-12 23:34
     */
    public function getApiRoomList(array $where, $page, $limit, int $propertyId = null)
    {
        $query = $this->dao->search($where, $propertyId);
        $count = $query->count();
        $list = $query->page($page, $limit)
            ->with([
                'contractInfo' => function ($query) {
                    $query->field('id,number,status,start_date,end_date');
                },
            ])
            ->append(['picture', 'house_type', 'full_room_name', 'vacancy_day'])
            ->field('id,contract_id,room_name,status,unit_id,room_size,room_rent,room_num,hall_num,who_num,add_time,vacancy_time')
            ->hidden(['room_num', 'hall_num', 'who_num', 'add_time'])
            ->order('status', 'asc')
            ->select();
        return compact('count', 'list');
    }

    /**
     *  空置房间列表
     * @param array $where
     * @param $page
     * @param $limit
     * @param int|null $propertyId
     * @return array
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-06-12 23:34
     */
    public function getApiVacancyiList(array $where, $page, $limit, int $propertyId = null)
    {
        $query = $this->dao->search($where, $propertyId);
        $count = $query->count();
        $list = $query->page($page, $limit)
            ->append(['picture', 'label_list'])
            ->field('id,room_name,room_size,room_rent')
            ->orderRaw('rand()')
            ->select();
        return compact('count', 'list');
    }


    /**
     *  根据合同ID 获取房间列表
     * @param array $where
     * @param $page
     * @param $limit
     * @param int|null $propertyId
     * @return array
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-06-12 23:34
     */
    public function getApiContractIdVacancyiList(array $where, $page, $limit, int $propertyId = null)
    {
        $query = $this->dao->search($where, $propertyId);
        $count = $query->count();
        $list = $query->page($page, $limit)
            ->append(['full_room_name'])
            ->field('id,room_name,floor_name,unit_id')
            ->hidden(['room_name', 'floor_name', 'unit_id'])
            ->order('status', 'asc')
            ->select();
        return compact('count', 'list');
    }


    public function addInfo(array $data, int $userId = 0)
    {
        $picture = [];
        if (isset($data['picture'])) {
            $picture = $data['picture'];
        }
        unset($data['picture']);
        return Db::transaction(function () use ($data, $userId, $picture) {
            $labelIds = $data['label_id'];
            unset($data['label_id']);

            $data['status'] = 1;
            $data['add_uid'] = $userId;
            $resInfo = $this->dao->create($data);
            if ($picture) {
                /** @var RoomPictureRepository $pictureRepository */
                $pictureRepository = app()->make(RoomPictureRepository::class);
                $pictureRepository->addPicture($resInfo['id'], $picture);
            }
            if ($labelIds) {
                /** @var RoomBasicLabelRepository $roomBasicLabelRepository .php */
                $roomBasicLabelRepository = app()->make(RoomBasicLabelRepository::class);
                $insertData = [];
                foreach ($labelIds as $v) {
                    $insertData[] = [
                        'label_id' => $v,
                        'room_id' => $resInfo['id'],
                        'property_id' => $resInfo['property_id'],
                    ];
                }
                $roomBasicLabelRepository->insertAll($insertData);
            }
            /** @var PropertyUsersLogRepository $repository */
            $repository = app()->make(PropertyUsersLogRepository::class);
            $repository->addInfo($resInfo['property_id'], $userId, 'ROOM.BASIC.ADD', $data);
            event('room.create', [
                'userId' => $userId,
                'roomInfo' => $resInfo,
            ]);
            return $resInfo;
        });
    }

    public function copynfo($info, array $data, int $userId = 0)
    {
        $picture = [];
        if (isset($data['picture'])) {
            $picture = $data['picture'];
        }
        unset($data['picture']);
        return Db::transaction(function () use ($info, $data, $userId, $picture) {
            $labelIds = $data['label_id'];
            unset($data['label_id']);

            $data['status'] = 1;
            $data['unit_id'] = $info['unit_id'];
            $data['property_id'] = $info['property_id'];
            $resInfo = $this->dao->create($data);
            if ($picture) {
                /** @var RoomPictureRepository $pictureRepository */
                $pictureRepository = app()->make(RoomPictureRepository::class);
                $pictureRepository->addPicture($resInfo['id'], $picture);
            }
            if ($labelIds) {
                /** @var RoomBasicLabelRepository $roomBasicLabelRepository .php */
                $roomBasicLabelRepository = app()->make(RoomBasicLabelRepository::class);
                $insertData = [];
                foreach ($labelIds as $v) {
                    $insertData[] = [
                        'label_id' => $v,
                        'room_id' => $resInfo['id'],
                        'property_id' => $resInfo['property_id'],
                    ];
                }
                $roomBasicLabelRepository->insertAll($insertData);
            }
            /** @var PropertyUsersLogRepository $repository */
            $repository = app()->make(PropertyUsersLogRepository::class);
            $repository->addInfo($info['property_id'], $userId, 'ROOM.BASIC.COPY', $data);
            event('room.create', [
                'userId' => $userId,
                'roomInfo' => $resInfo,
                'remark' => '复制 ID' . $info['id'],
            ]);
            return $resInfo;
        });
    }

    public function editInfo($info, array $data, int $userId = 0)
    {
        $picture = null;
        if (isset($data['picture'])) {
            $picture = (array)$data['picture'];
        }
        unset($data['picture']);
        return Db::transaction(function () use ($data, $info, $userId, $picture) {
            $labelIds = $data['label_id'];
            unset($data['label_id']);

            /** @var PropertyUsersLogRepository $repository */
            $repository = app()->make(PropertyUsersLogRepository::class);
            $repository->addInfo($info['property_id'], $userId, 'ROOM.BASIC.EDIT', $data);

            /** @var RoomPictureRepository $pictureRepository */
            $pictureRepository = app()->make(RoomPictureRepository::class);
            $pictureRepository->removePicture($info['id']);
            if ($picture) {
                $resB = $pictureRepository->addPicture($info['id'], $picture);
            }

            /** @var RoomBasicLabelRepository $roomBasicLabelRepository .php */
            $roomBasicLabelRepository = app()->make(RoomBasicLabelRepository::class);
            $roomBasicLabelRepository->deleteByRoomId($info['id']);
            if ($labelIds) {
                $insertData = [];
                foreach ($labelIds as $v) {
                    $insertData[] = [
                        'label_id' => $v,
                        'room_id' => $info['id'],
                        'property_id' => $info['property_id'],
                    ];
                }
                $resC = $roomBasicLabelRepository->insertAll($insertData);
            }

            $res = $this->dao->update($info['id'], $data);

            event('room.redact', [
                'userId' => $userId,
                'roomInfo' => $info,
            ]);
            return ($res || $resB || $resC);
        });
    }


    public function getDetail(int $id)
    {
        $data = $this->dao->search([])
            ->append(['full_room_name', 'house_type'])
            ->where('id', $id)
            ->find();
        return $data;
    }

    /**
     *  房间详情页
     * @param int $id
     * @return array|mixed|\think\db\BaseQuery|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-06-13 17:03
     */
    public function getApiDetail(int $id)
    {
        $data = $this->dao->getSearch([])
            ->with([
                'contractInfo' => function ($query) {
                    $query->field('id,room_id,number,start_date,end_date');
                }
            ])
            ->append(['picture', 'house_type', 'full_room_name', 'vacancy_day', 'lave_days', 'contract_rent', 'contract_deposit'])
            ->field('id,contract_id,room_name,floor_total,floor_name,status,unit_id,room_size,room_rent,room_num,hall_num,who_num,add_time,vacancy_time')
            ->hidden(['room_num', 'hall_num', 'who_num', 'add_time'])
            ->where('id', $id)
            ->find();
        ## 楼层信息
        $data['floor_type_name'] = ($data['floor_name'] ? ('第 ' . $data['floor_name'] . ' 层') : '') . ($data['floor_total'] ? (' 共 ' . $data['floor_total'] . ' 层') : '');
        unset($data['floor_total']);
        unset($data['contract_id']);
        return $data;
    }

    public function batchDelete(array $ids, int $userId = 0)
    {
        $list = $this->dao->selectWhere([
            ['id', 'in', $ids], ['status', 'in', [1]]
        ], 'id,property_id,status,room_name');
        if ($list) {
            foreach ($list as $k => $v) {
                $this->deleteInfo($v, $userId);
            }
            return $list;
        }
        return [];
    }

    public function deleteInfo($info, int $userId = 0)
    {
        return Db::transaction(function () use ($info, $userId) {
            event('room.delete', [
                'userId' => $userId,
                'roomInfo' => $info,
            ]);

            /** @var PropertyUsersLogRepository $repository */
            $repository = app()->make(PropertyUsersLogRepository::class);
            $repository->addInfo($info['property_id'], $userId, 'ROOM.BASIC.DEL', $info);
            $this->dao->delete($info['id']);

        });
    }


    /**
     * 检测房间信检测删除条件
     * @param $roomInfo
     * @return true
     *
     * @author Amos
     * 2024-06-13 15:28
     */
    public function deleteCheck($roomInfo)
    {
        if ($roomInfo['contract_id'] > 0 || $roomInfo['status'] == 2) {
            throw new ValidateException('该房间存在进行中的租赁无法删除');
        }
        return true;
    }

    /**
     *  房间出租
     * @param int $roomId
     * @param int $contractId
     * @param int $userId
     * @return int
     * @throws \think\db\exception\DbException
     *
     * @author Amos
     * 2024-03-20 10:32
     */
    public function roomRentStatus(int $roomId, int $contractId, int $userId = 0)
    {
        $res = $this->dao->update($roomId, ['contract_id' => $contractId, 'status' => 2]);
        event('room.rent', [
            'userId' => $userId,
            'roomId' => $roomId,
            'contractId' => $contractId,
        ]);
        return $res;
    }


    /**
     * 房间退租
     * @param int $roomId 房间ID
     * @return int
     * @throws \think\db\exception\DbException
     */
    public function roomRelieve(int $roomId, int $contractId, int $userId = 0)
    {
        $res = $this->dao->update($roomId, [
            'contract_id' => 0,
            'status' => 1,
            'vacancy_time' => date('Y-m-d')
        ]);
        event('room.relieve', [
            'userId' => $userId,
            'roomId' => $roomId,
            'contractId' => $contractId,
        ]);
        return $res;
    }


}